/*
 * BuiltInFrameDialog.java
 *
 * Created on Oct 1, 2011, 10:06:00 AM
 */
package com.photoexpert;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;

/**
 *
 * @author PANYIXIN
 */
class BuiltInFrameDialog extends javax.swing.JDialog {

    BuiltInFrameDialog() {
        super(App.Instance(), true);
        initComponents();
        setLocation(200, 200);
        _flavor.setSelectedIndex(0);
        setVisible(true);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        _frameSizeGroup = new javax.swing.ButtonGroup();
        _previewPane = new FramePreviewPane();
        _cancel = new javax.swing.JButton();
        _ok = new javax.swing.JButton();
        _flavorLabel = new javax.swing.JLabel();
        _flavor = new javax.swing.JComboBox();
        jScrollPane1 = new javax.swing.JScrollPane();
        _list = new javax.swing.JList();
        _previewLabel = new javax.swing.JLabel();
        _keepSize = new javax.swing.JCheckBox();
        _frameViewPane = new FrameViewPane();
        _keepFrameWidth = new javax.swing.JRadioButton();
        _keepFrameRatio = new javax.swing.JRadioButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Built in frames");
        setModal(true);

        javax.swing.GroupLayout _previewPaneLayout = new javax.swing.GroupLayout(_previewPane);
        _previewPane.setLayout(_previewPaneLayout);
        _previewPaneLayout.setHorizontalGroup(
            _previewPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 311, Short.MAX_VALUE)
        );
        _previewPaneLayout.setVerticalGroup(
            _previewPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 172, Short.MAX_VALUE)
        );

        _cancel.setText("Cancel");
        _cancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                _cancelActionPerformed(evt);
            }
        });

        _ok.setText("OK");
        _ok.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                _okActionPerformed(evt);
            }
        });

        _flavorLabel.setText("Flavor:");

        _flavor.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Wood flavor", "Metal flavor" }));
        _flavor.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                _flavorActionPerformed(evt);
            }
        });

        _list.setModel(_listModel);
        _list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        _list.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                _listValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(_list);

        _previewLabel.setText("Preview:");

        _keepSize.setText("Keep image size");
        _keepSize.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                _keepSizeActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout _frameViewPaneLayout = new javax.swing.GroupLayout(_frameViewPane);
        _frameViewPane.setLayout(_frameViewPaneLayout);
        _frameViewPaneLayout.setHorizontalGroup(
            _frameViewPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 226, Short.MAX_VALUE)
        );
        _frameViewPaneLayout.setVerticalGroup(
            _frameViewPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 91, Short.MAX_VALUE)
        );

        _frameSizeGroup.add(_keepFrameWidth);
        _keepFrameWidth.setSelected(true);
        _keepFrameWidth.setText("Keep frame width");

        _frameSizeGroup.add(_keepFrameRatio);
        _keepFrameRatio.setText("Keep frame ratio");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(_flavorLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(_flavor, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(_previewPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(_cancel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE)
                            .addComponent(_ok, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 196, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(_keepSize)
                            .addComponent(_previewLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(_keepFrameWidth)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(_keepFrameRatio))
                            .addComponent(_frameViewPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(_flavorLabel)
                    .addComponent(_flavor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(_frameViewPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 91, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(_keepSize)
                    .addComponent(_keepFrameWidth)
                    .addComponent(_keepFrameRatio))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(_previewLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(_previewPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(_ok)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(_cancel)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void _okActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__okActionPerformed
        BufferedImage destination;
        int w1 = _image.getWidth();
        int h1 = _image.getHeight();
        int north = _depthNorth;
        int west = _depthWest;
        int south = _depthSouth;
        int east = _depthEast;
        int north1 = north;
        int west1 = west;
        int south1 = south;
        int east1 = east;
        Graphics g;
        if(_keepSize.isSelected()) {
            destination = _image;
            g = destination.createGraphics();
        } else {
            // create new image because size changed
            int imgWidth = w1;
            int imgHeight = h1;
            if(_keepFrameWidth.isSelected()) {
                w1 = w1 + west1 + east1;
                h1 = h1 + north1 + south1;
            } else {
                int w2 = (int)(w1 * _frameImageWidth * 1d / (_frameImageWidth - west - east));
                west1 = (int)(west * w2 * 1d / _frameImageWidth);
                east1 = (int)(east * w2 * 1d / _frameImageWidth);
                w1 = w2;
                int h2 = (int)(h1 * _frameImageHeight * 1d / (_frameImageHeight - north - south));
                north1 = (int)(north * h2 * 1d / _frameImageHeight);
                south1 = (int)(south * h2 * 1d / _frameImageHeight);
                h1 = h2;
            }
            int imgType = _image.getTransparency() == Transparency.OPAQUE ?
                BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
            destination = new BufferedImage(w1, h1, imgType);
            g = destination.createGraphics();
            g.drawImage(_image, west1, north1, imgWidth, imgHeight, null);
        }
        if(_keepFrameWidth.isSelected()) {
            BufferedImage img = _frameImage.getSubimage(0, 0, west, north);
            g.drawImage(img, 0, 0, west1, north1, null);
            img = _frameImage.getSubimage(west, 0, _frameImageWidth - west - east, north);
            g.drawImage(img, west1, 0, w1 - west1 - east1, north1, null);
            img = _frameImage.getSubimage(_frameImageWidth - east, 0, east, north);
            g.drawImage(img, w1 - east1, 0, east1, north1, null);
            img = _frameImage.getSubimage(0, north, west, _frameImageHeight - north - south);
            g.drawImage(img, 0, north1, west1, h1 - north1 - south1, null);
            img = _frameImage.getSubimage(_frameImageWidth - east, north,
                east, _frameImageHeight - north - south);
            g.drawImage(img, w1 - east1, north1, east1, h1 - north1 - south1, null);
            img = _frameImage.getSubimage(0, _frameImageHeight - south, west, south);
            g.drawImage(img, 0, h1 - south, west1, south1, null);
            img = _frameImage.getSubimage(west, _frameImageHeight - south,
                _frameImageWidth - west - east, south);
            g.drawImage(img, west, h1 - south1, w1 - west1 - east1, south1, null);
            img = _frameImage.getSubimage(_frameImageWidth - east,
                _frameImageHeight - south, east, south);
            g.drawImage(img, w1 - east1, h1 - south1, east1, south1, null);
        } else {
            g.drawImage(_frameImage, 0, 0, w1, h1, null);
        }
        g.dispose();
        _implementor.setImage(destination);
        setVisible(false);
        dispose();
    }//GEN-LAST:event__okActionPerformed

    private void _cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__cancelActionPerformed
        setVisible(false);
        dispose();
    }//GEN-LAST:event__cancelActionPerformed

    private void _keepSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__keepSizeActionPerformed
        _previewPane.repaint();
    }//GEN-LAST:event__keepSizeActionPerformed

    private void _flavorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__flavorActionPerformed
        int flavor = _flavor.getSelectedIndex();
        _listModel.clear();
        int size = _frames[flavor].length;
        for(int i = 0; i < size; ++i)
            _listModel.addElement(_frames[flavor][i]);
    }//GEN-LAST:event__flavorActionPerformed

    private void _listValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event__listValueChanged
        if(_list.getSelectedIndex() < 0)
            return;
        String frame = (String)(_list.getSelectedValue());
        String imgLocation = "images/frames/" + frame + ".jpg";
        URL imgURL = App.class.getResource(imgLocation);
        try {
            _frameImage = ImageIO.read(imgURL);
            _frameViewPane.repaint();
            _frameImageWidth = _frameImage.getWidth();
            _frameImageHeight = _frameImage.getHeight();
            _depthNorth = 0;
            _depthEast = 0;
            _depthSouth = 0;
            _depthWest = 0;
            int t = _frameImageHeight / 2;
            for(int i = 0; i < _frameImageWidth; ++i) {
                int rgb = _frameImage.getRGB(i, t);
                if((rgb & 0xff000000) == 0x00000000) {
                    _depthWest = i;
                    break;
                }
            }
            for(int i = 0; i < _frameImageWidth; ++i) {
                int rgb = _frameImage.getRGB(_frameImageWidth - 1 - i, t);
                if((rgb & 0xff000000) == 0x00000000) {
                    _depthEast = i;
                    break;
                }
            }
            t = _frameImageWidth / 2;
            for(int i = 0; i < _frameImageHeight; ++i) {
                int rgb = _frameImage.getRGB(t, i);
                if((rgb & 0xff000000) == 0x00000000) {
                    _depthNorth = i;
                    break;
                }
            }
            for(int i = 0; i < _frameImageHeight; ++i) {
                int rgb = _frameImage.getRGB(t, _frameImageHeight - 1 - i);
                if((rgb & 0xff000000) == 0x00000000) {
                    _depthSouth = i;
                    break;
                }
            }
            _previewPane.repaint();
        } catch (IOException ex) {
            _frameImage = null;
            App._logger.log(Level.SEVERE, "Unable to open frame {0}", frame);
        }
    }//GEN-LAST:event__listValueChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton _cancel;
    private javax.swing.JComboBox _flavor;
    private javax.swing.JLabel _flavorLabel;
    private javax.swing.ButtonGroup _frameSizeGroup;
    private javax.swing.JPanel _frameViewPane;
    private javax.swing.JRadioButton _keepFrameRatio;
    private javax.swing.JRadioButton _keepFrameWidth;
    private javax.swing.JCheckBox _keepSize;
    private javax.swing.JList _list;
    private javax.swing.JButton _ok;
    private javax.swing.JLabel _previewLabel;
    private javax.swing.JPanel _previewPane;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration//GEN-END:variables
    private Implementor         _implementor = Implementor.Instance();
    private BufferedImage       _image = Implementor.Instance().getImage();
    private String[][]          _frames = {
        {"wood1", "wood2", "wood3", "wood4", "wood5", "wood6", "wood7" },
        {"metal1", "metal2", "metal3", "metal4", "metal5", "metal6", "metal7", "metal8", "metal9"}
    };
    private DefaultListModel    _listModel = new DefaultListModel();
    private BufferedImage       _frameImage = null;
    private int                 _frameImageWidth = 0;
    private int                 _frameImageHeight = 0;
    private int                 _depthNorth = 0;
    private int                 _depthEast = 0;
    private int                 _depthSouth = 0;
    private int                 _depthWest = 0;

    private class FramePreviewPane extends JPanel {
        @Override
        public void paint(Graphics g) {
            if(_frameImage == null)
                return;
            Dimension screen = _previewPane.getSize();
            int sw = screen.width;
            int sh = screen.height;
            BufferedImage img1 = _frameImage.getSubimage(0, 0, sw, sh);
            g.drawImage(img1, 0, 0, null);
            BufferedImage img2;
            if(_keepSize.isSelected())
                img2 = _image.getSubimage(_depthWest, _depthNorth,
                    sw - _depthWest, sh - _depthNorth);
            else
                img2 = _image.getSubimage(0, 0, sw - _depthWest, sh - _depthNorth);
            g.drawImage(img2, _depthWest, _depthNorth, null);
        }
    }

    private class FrameViewPane extends JPanel {
        @Override
        public void paint(Graphics g) {
            Dimension d = _frameViewPane.getSize();
            int w = d.width;
            int h = d.height;
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, w, h);
            if(w * 1.0 / _frameImageWidth > h * 1.0 / _frameImageHeight)
                w = (int)(h * 1.0 / _frameImageHeight * _frameImageWidth);
            else if(w * 1.0 / _frameImageWidth < h * 1.0 / _frameImageHeight)
                h = (int)(w * 1.0 / _frameImageWidth * _frameImageHeight);
            g.drawImage(_frameImage, 0, 0, w, h, null);
        }
    }
}
